﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BbsbWebService.Classes;
using BbsbWebService.Repositories.Client;
using BbsbWebService.Repositories.Server;
using BbsbWebService.Tasks;
using BbsbWebService.Enums;

namespace BbsbWebService.Repositories
{
    public static class RepositoryInstances
    {
        private static PowerRepositoryBase<Group> _groupRepository;
        private static PowerRepositoryBase<ControllableItem> _itemRepository;
        private static RepositoryBase<BaseTask> _taskRepository;

        public static PowerRepositoryBase<Group> GroupRepository
        {
            get
            {
                if (_groupRepository == null)
                {
                    if (ApplicationState.IsConnectedToClient)
                    {
                        _groupRepository = new ClientGroupRepository();
                    }
                    else
                    {
                        _groupRepository = new ServerGroupRepository();
                    }
                }
                return _groupRepository;
            }
        }

        public static PowerRepositoryBase<ControllableItem> ItemRepository
        {
            get
            {
                if (_itemRepository == null)
                {
                    if (ApplicationState.IsConnectedToClient)
                    {
                        _itemRepository = new ClientItemRepository();

                    }
                    else
                    {
                        _itemRepository = new ServerItemRepository();
                    }
                }
                return _itemRepository;
            }
        }

        public static RepositoryBase<BaseTask> TaskRepository
        {
            get
            {
                if (_taskRepository == null)
                {
                    if (ApplicationState.IsConnectedToClient)
                    {
                        _taskRepository = new ClientTaskRepository();
                    }
                    else
                    {
                        _taskRepository = new ServerTaskRepository();
                    }
                }
                return _taskRepository;
            }
        }

        public static PowerState SendPower(Guid id, PowerOption option)
        {
            PowerState retVal = PowerState.Unknown;

            if (ItemRepository.HasItem(id))
            {
                retVal = ItemRepository.SendPower(id, option);
            }
            else if (GroupRepository.HasItem(id))
            {
                retVal = GroupRepository.SendPower(id, option);
            }

            return retVal;
        }

        public static void DecypherAndInterpret(string command)
        {
            CommandItem item = null;
            string itemCommand = command.Substring(1);

            // Loop through both items and groups looking for a command....
            if (RepositoryInstances.ItemRepository.Items.Any(o => string.Equals(o.Command, itemCommand, StringComparison.InvariantCultureIgnoreCase)))
            {
                item = RepositoryInstances.ItemRepository.Items.Single(o => string.Equals(o.Command, itemCommand, StringComparison.InvariantCultureIgnoreCase));
            }
            else if (RepositoryInstances.GroupRepository.Items.Any(o => string.Equals(o.Command, itemCommand, StringComparison.InvariantCultureIgnoreCase)))
            {
                item = RepositoryInstances.GroupRepository.Items.Single(o => string.Equals(o.Command, itemCommand, StringComparison.InvariantCultureIgnoreCase));
            }

            if (item != null)
            {
                int responseState = Convert.ToInt32(command.Substring(0, 1));
                if (item is ControllableItem)
                {
                    PowerState state = (PowerState)responseState;
                    RepositoryInstances.ItemRepository.UpdateState(item.Id, state);
                }
                else if (item is Group)
                {
                    PowerOption option = (PowerOption)responseState;
                    RepositoryInstances.GroupRepository.SendPower(item.Id, option);
                }
            }
        }

        public static BaseItem GetItem(Guid id)
        {
            BaseItem item = null;

            if (ItemRepository.HasItem(id))
            {
                item = ItemRepository.GetItem(id);
            }
            else if (GroupRepository.HasItem(id))
            {
                item = GroupRepository.GetItem(id);
            }

            return item;
        }

        public static void Reset()
        {
            _groupRepository = null;
            _itemRepository = null;
            _taskRepository = null;
        }

        public static void Refresh()
        {
            RepositoryInstances.Reset();

            RepositoryInstances.GroupRepository.Initialise();

            RepositoryInstances.ItemRepository.Initialise();

            RepositoryInstances.TaskRepository.Initialise();
        }
    }
}
